#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time   : 2023-11-25 13:56
# @Author : hard work
# @File    : renix_base.py
# @Description :
import logging
import os
import time

from renix_py_api.api_gen import Port, BringPortsOnlineCommand, Interface, ReleasePortCommand, \
    SaveTestCaseCommand, StartAllStreamCommand, StopAllStreamCommand, PageResultView, ResultQuery, \
    SubscribeResultCommand, ConnectChassisCommand, DisconnectChassisCommand, ConfigurePortsCommand, \
    EnumTransmitMode, EnumErrorGen, EnumLoadProfileType, EnumIgnoreLinkState, EnumTimeStampPos, EnumCaptureMode, \
    EnumCacheCapacity, EnumBufferFullAction, CommitCommand, DownloadCaptureDataCommand, StopCaptureCommand, \
    StopAllCaptureCommand
from renix_py_api.renix import initialize
from renix_py_api.renix_common_api import get_sys_entry, renix_info

from traffic_tool.tool_renix.renix_empty.renix_basic_empty import Renix_basic_config
from common.renix_basic_config.renix_config import renix_config


def set_renix_config_commit():
    """Commit the above configuration before running the streams"""
    commit_cmd = CommitCommand()

    commit_cmd.execute()


def set_tx_traffic_start():
    # 发送流量
    StartAllStreamCommand().execute()
    time.sleep(3)
    StopAllStreamCommand().execute()


def set_save_renix_config(dirname, tempfilename):
    # dirname, tempfilename = os.path.split(os.path.abspath(__file__))
    filename, extension = os.path.splitext(tempfilename)
    SaveTestCaseCommand(TestCase=f'{dirname}/xcfg/{filename}.xcfg').execute()


def renix_info_log(strs):
    renix_info(strs)


class Renix_base(Renix_basic_config):
    """脚本设计思路：初始化 API—>占用端口—>配置流量—>订
    阅统计—>启动测试—>停止测试—>分析统计—>判断结果"""

    def __init__(self, **kwargs):
        super().__init__()

        if renix_config():
            """使用配置文件(../common/renix_basic_config/renix_config.py)中的配置"""
            Renix_basic_config.chassis_address = renix_config()['chassis_address']
            Renix_basic_config.slot = renix_config()['slot']
            Renix_basic_config.port1 = renix_config()['port1']
            Renix_basic_config.port2 = renix_config()['port2']
            Renix_basic_config.port3 = renix_config()['port3']
            Renix_basic_config.port4 = renix_config()['port4']
            Renix_basic_config.port5 = renix_config()['port5']
            Renix_basic_config.renix_install_addr = renix_config()['renix_install_addr']
            print(1)
        else:
            print(11)

            """使用自定义配置"""
            if not kwargs:
                return
            # 如果不使用默认配置，此处修改你自己的配置
            Renix_basic_config.chassis_address = kwargs['chassis_address']
            Renix_basic_config.slot = kwargs['slot']
            Renix_basic_config.port1 = kwargs['port1']
            Renix_basic_config.port2 = kwargs['port2']
            Renix_basic_config.port3 = kwargs['port3']
            Renix_basic_config.port4 = kwargs['port4']
            Renix_basic_config.port5 = kwargs['port5']
            Renix_basic_config.renix_install_addr = kwargs['renix_install_addr']

        # Renix_basic_config().set_renix_SysVariable()

        self.chassis = None
        self.Port_1 = None
        self.Port_2 = None
        self.Port_3 = None
        self.sys_entry = None
        self.interface1 = None
        self.interface2 = None
        self.interface3 = None
        self.stream_result_query = None
        self.rx_cap_conf_1 = None
        self.rx_cap_conf_2 = None

    def set_renix_init(self):
        renix_info_log('set_renix_init')
        """renix initialize and connect chassis and reserve port"""
        initialize()
        self.sys_entry = get_sys_entry()
        self.chassis = ConnectChassisCommand(self.chassis_address)
        self.chassis.execute()
        # assert self.chassis.handle  # 判断机箱是否在线，避免长时间等待
        self.Port_1 = Port(upper=self.sys_entry, Location='//%s/%s/%s' % (self.chassis_address, self.slot, self.port1))
        self.Port_2 = Port(upper=self.sys_entry, Location='//%s/%s/%s' % (self.chassis_address, self.slot, self.port2))
        self.Port_3 = Port(upper=self.sys_entry, Location='//%s/%s/%s' % (self.chassis_address, self.slot, self.port3))
        # some port added to here if you need
        online_command = BringPortsOnlineCommand(PortList=[self.Port_1.handle, self.Port_2.handle, self.Port_3.handle])
        online_command.execute()
        print('端口上线', online_command.PortList)
        assert self.Port_1.Online
        self.interface1 = Interface(upper=self.Port_1)
        self.interface2 = Interface(upper=self.Port_2)
        self.interface3 = Interface(upper=self.Port_3)

    def set_tx_rx_port_model(self, speed=1024):
        """ set renix port model
        :param speed:
                    SPEED_10M(256)
                    SPEED_100M(512)
                    SPEED_1G(1024)
        :return:
        """
        if speed:
            configure_port_cmd = ConfigurePortsCommand(PortList=self.Port_1, LineSpeed=1024, AutoNegotiation=False,
                                                       FlowControl=0, Duplex=1)
            configure_port_cmd.execute()
            time.sleep(3)
            configure_port_cmd = ConfigurePortsCommand(PortList=self.Port_2, LineSpeed=1024, AutoNegotiation=False,
                                                       FlowControl=0, Duplex=1)
            configure_port_cmd.execute()
            time.sleep(3)
            configure_port_cmd = ConfigurePortsCommand(PortList=self.Port_3, LineSpeed=1024, AutoNegotiation=False,
                                                       FlowControl=0, Duplex=1)
            configure_port_cmd.execute()
            time.sleep(3)

        else:
            return

    def set_txGenerator_and_txStart(self, **kwargs):
        renix_info_log('set_txGenerator_and_txStart')
        if kwargs:
            pass
        else:
            TransmitMode = kwargs['TransmitMode']
            """TransmitMode type: CONTINUOUS(0) BURST(1) TIME(2) STEP(3) ONSTREAM(4)"""
            GenerateError = kwargs['GenerateError']
            """GenerateError type: NO_ERROR(0) CRC(1)"""
            LoadProfileType = kwargs['LoadProfileType']
            """LoadProfileType type: PORT_BASE(0) STREAM_BASE(1) PRIORITY_BASE(2) MANUAL_BASE(3)"""
            BurstSize = kwargs['BurstSize']
            """BurstSize type: uint64 in [1,4294967295]"""

            stream_port_config = self.Port_1.get_children('StreamPortConfig')[0]

            stream_port_config.edit(TransmitMode=EnumTransmitMode.BURST, GenerateError=EnumErrorGen.CRC,
                                    LoadProfileType=EnumLoadProfileType.STREAM_BASE,
                                    IgnoreLinkState=EnumIgnoreLinkState.YES,
                                    TimeStampPosTx=EnumTimeStampPos.TIMESTAMP_TAIL,
                                    TimeStampPosRx=EnumTimeStampPos.TIMESTAMP_TAIL, LatencyCompensationTx=10000,
                                    LatencyCompensationRx=10000)


    def set_capture_start(self):
        renix_info_log('set_capture_start')
        self.rx_cap_conf_1 = self.Port_2.get_children('CaptureConfig')[0]
        self.rx_cap_conf_1.edit(CaptureMode=EnumCaptureMode.CTRL_PLANE, CacheCapacity=EnumCacheCapacity.Cache_64KB,
                                BufferFullAction=EnumBufferFullAction.WRAP, StartingFrameIndex=10,
                                AttemptDownloadPacketCount=1000)
        self.rx_cap_conf_2 = self.Port_3.get_children('CaptureConfig')[0]
        self.rx_cap_conf_2.edit(CaptureMode=EnumCaptureMode.CTRL_PLANE, CacheCapacity=EnumCacheCapacity.Cache_64KB,
                                BufferFullAction=EnumBufferFullAction.WRAP, StartingFrameIndex=10,
                                AttemptDownloadPacketCount=1000)

    def get_rx_stream_summary(self):
        # 获取流量StreamTemplate_1的StreamBlockStats统计结果
        streamblock_stats = self.stream_result_query.get_children('StreamBlockStats')
        print(streamblock_stats[0].__dict__)
        TxStreamFrames = streamblock_stats[0].TxStreamFrames
        RxStreamFrames = streamblock_stats[0].RxStreamFrames
        print('TxStreamFrames: {}'.format(TxStreamFrames))
        print('RxStreamFrames: {}'.format(RxStreamFrames))

    def set_TxStream_and_RxCapture_stop(self):
        """stop traffic ,and stop capture"""

        renix_info_log('set_TxStream_and_RxCapture_stop')
        stop_all_stream_cmd = StopAllStreamCommand()

        stop_all_stream_cmd.execute()

        stop_cap_cmd1 = StopCaptureCommand(CaptureConfigs=self.rx_cap_conf_1.handle)

        stop_cap_cmd1.execute()

        stop_cap_cmd2 = StopCaptureCommand(CaptureConfigs=self.rx_cap_conf_2.handle)

        stop_cap_cmd2.execute()

        stop_all_cap_cmd = StopAllCaptureCommand()
        stop_all_cap_cmd.execute()

    def set_capture_save(self, file_dir, file1, file2):
        renix_info_log('set_capture_save')
        # if os.path.isdir(file_dir):
        #     if os.path.isfile(file1) and os.path.isfile(file2):
        #         os.remove(file1)
        #         os.remove(file2)

        download_cap_data_cmd1 = DownloadCaptureDataCommand(CaptureConfigs=self.rx_cap_conf_1.handle,
                                                            FileDir=file_dir,
                                                            FileName=file1, MaxDownloadDataCount=50)

        download_cap_data_cmd1.execute()

        download_cap_data_cmd2 = DownloadCaptureDataCommand(CaptureConfigs=self.rx_cap_conf_1.handle,
                                                            FileDir=file_dir,
                                                            FileName=file2, MaxDownloadDataCount=50)

        download_cap_data_cmd2.execute()

    def set_Renix_destroy(self):
        # 释放端口
        renix_info_log('destroy project')
        # stream1 = self.Port_1.get_children(relative_name='StreamTemplate')
        # stream1.delete()
        # release_port_cmd = ReleasePortCommand(LocationList=[self.Port_1, self.Port_2, self.Port_3]).execute()
        # release_port_cmd.execute()
        self.chassis = DisconnectChassisCommand(ChassisList=['HardwareChassis_1'])
        self.chassis.execute()


if __name__ == '__main__':
    renix = Renix_base()
